package com.intretech.tj.gpp.pathfinding

import com.intretech.tj.gpp.Graph
import com.intretech.tj.gpp.entity.DO.Edge
import com.intretech.tj.gpp.entity.DTO.light.LightStatus
import jakarta.enterprise.context.ApplicationScoped
import jakarta.inject.Inject

@ApplicationScoped
class NormalWeightStrategy @Inject constructor(
    private val graph: Graph
) : WeightStrategy {
    override fun calculate(edge: Edge): Long {
        // 1. 基础权重
        var weight = edge.weight

        // 2. 考虑车辆数量
        val vehiclesOnEdge = graph.getVehiclesOnEdge(edge.id)
        if (vehiclesOnEdge >= edge.maxCar) {
            return Int.MAX_VALUE.toLong() // 路段已满，暂时视为不可通行
        }
        // 车辆越多，权重越高
        weight += vehiclesOnEdge * 100 // 这个乘数可以根据实际情况调整

        // 3. 考虑红绿灯
        val endNode = graph.getNode(edge.rfidNodeEnd)
        if (endNode?.lightId != null) {
            when (graph.getTrafficLightStatus(endNode.id)) {
                LightStatus.RED -> weight += 1000 // 红灯增加巨大权重
                LightStatus.YELLOW -> weight += 500 // 黄灯增加较大权重
                else -> { /* GREEN or null, no change */
                }
            }
        }

        // 4. 新增: 考虑目标节点的容量
        if (endNode != null) {
            val vehiclesAtNode = graph.getVehiclesAtNode(edge.rfidNodeEnd)
            if (vehiclesAtNode >= endNode.capacity) {
                // 目标节点已满，增加巨大权重以避开此路径
                return Int.MAX_VALUE.toLong()
            }
        }

        // 5. 考虑停车场路段（低优先级）
        if (edge.parkingRoad) {
            return (Int.MAX_VALUE / 2).toLong()
        }

        // 6. 考虑禁用边 (最低优先级)
        if (graph.isEdgeDisabled(edge.id)) {
            return (Int.MAX_VALUE).toLong()
        }

        return weight.toLong()
    }

    override fun mark(): String {
        return "Normal"
    }
}